#ifndef __NET_CONNECTION_REQUEST_PACKET_H__
#define __NET_CONNECTION_REQUEST_PACKET_H__

#include <cstdint>
#include <atomic>
#include "NetPeer.h"
#include "NetPacket.h"
#include "asio.hpp"

namespace LiteNetLib
{
    class NetManager;

    typedef asio::ip::udp::endpoint net_endpoint;

    class NetConnectRequestPacket
    {
    public:
        const int32_t headerSize = 14;
        int64_t connectionTime;
        uint8_t connectionNumber;
        net_endpoint targetEndpoint;
        NetDataReader netDataReader;

    private:
        NetConnectRequestPacket(int64_t theConnectionTime, uint8_t theConnectionNumber, net_endpoint *theTargetAddress, const NetDataReader &reader);

    public:
        ~NetConnectRequestPacket();

        static int32_t GetProtocolId(const char *rawData);

        static NetConnectRequestPacket* FromData(NetPacket *packet, net_endpoint *endpoint);

        // static NetPacket *Make(const char* buff, uint32_t buffLength, net_endpoint *address, int64_t connectId);
    };


    class NetConnectAcceptPacket
    {
    public:
        const int32_t size = 11;
        int64_t connectionId;
        uint8_t connectionNumber;
        bool isReusedPeer;

    private:
        // NetConnectAcceptPacket(int64_t thsConnectionId, uint8_t theConnectionNumber, bool thsIsReusedPeer);

    public:
        // static NetConnectAcceptPacket *FromData(NetPacket *packet);

        static NetPacket *Make(int64_t connectionId, uint8_t connectionNumber, bool isReusedPeer);
    };


    enum class ConnectionRequestResult
    {
        None,
        Accept,
        Reject,
        RejectForce
    };

    class ConnectionRequest
    {
    private:
        NetManager *m_listener;
        std::atomic<bool> m_used;

    public:
        ConnectionRequestResult result = ConnectionRequestResult::None;
        int64_t connectionTime;
        uint8_t connectionNumber;
        net_endpoint endpoint;
        NetDataReader netDataReader;

    public:
        ConnectionRequest(int64_t theConnectionId, uint8_t theConnectionNumber, const NetDataReader &reader, net_endpoint *theAddress, NetManager *theListerner);
        ~ConnectionRequest();

        bool tryActivate();

        void updateRequest(NetConnectRequestPacket *connRequest);

        NetPeerPtr accept();

        void reject(const char *rejectData, uint32_t rejectDataLength, bool force);

        void reject();
    };


} // namespace LiteNetLib

#endif
